// ====================HandCardContainer====================

class HandCardContainer extends CardContainerBase {
    initialize(opts) {
        /**
         * 存储所有卡牌精灵的数组，通过索引调取
         * @type {[Sprite_HandCard]}
         * @private
         */
        this._cardSprite = [];
        this._idleCard = [];
        this._usedCard = [];
        this._draging = false;
        this._lastTouchPos = new Point(0, 0);
        this._target = -1;
        this._selectMode = false;
        this._selectCallback = null;
        this.count = 0;
        this.current = null;
        this.createCardSprite();
    }

    createCardSprite() {
        const {maxAmount, libraryX, libraryY} = this._opts;
        const cardOpts = {
            width: 200,
            height: 300,
            r: 10,
            rim: 3
        };
        for (let i = 0; i < maxAmount; i++) {
            const cardSprite = new Sprite_HandCard(cardOpts);
            cardSprite.hide();
            cardSprite.move(libraryX, libraryY);
            this._cardSprite[i] = cardSprite;
            this._idleCard.push(i);
            this.addChild(cardSprite);
        }
    }

    setCurrent(cardSprite) {
        if (cardSprite !== null) {
            cardSprite.zIndex += 999;
            cardSprite.selected();
        }
        if (this.current !== null) {
            this.current.restore();
        }
        this.current = cardSprite;
        this.sortChildren();
    }

    /**
     * 抽牌
     * @param {Game_Card|Game_Card[]} card 卡牌
     * @param {Point} startPoint 起点
     */
    draw(card, startPoint) {
        const cards = [];
        const localPoint = this.toLocal(startPoint);
        if (Array.isArray(card)) {
            cards.push(...card);
        } else {
            cards.push(card);
        }
        for (let obj of cards) {
            const index = this._idleCard.shift();
            if (index === undefined) {
                console.error('没有多余的手牌精灵');
            }
            const cardSprite = this._cardSprite[index];
            this._usedCard.push(index);
            if (!!Point) cardSprite.move(localPoint.x, localPoint.y);
            cardSprite.setObject(obj);
            cardSprite.setOriginZIndex(this.count);
            cardSprite.zIndex = this.count++;
            cardSprite.show();
        }
        this.sort();
    }

    /**
     * 卡牌排序
     */
    sort() {
        const type = 0;
        const {width, height} = this._opts;
        const cardWidth = 200;
        const cardAmount = this._usedCard.length;
        switch (type) {
            // 顺序排列
            case 0: {
                const spacing = width >= (cardWidth + 10) * cardAmount - 10 ?
                    cardWidth + 10 :
                    (width - cardWidth) / (cardAmount - 1);

                for (let i = 0; i < cardAmount; i++) {
                    const index = this._usedCard[i];
                    const cardSprite = this._cardSprite[index];
                    const x = spacing * i + cardWidth / 2;
                    const y = height;
                    cardSprite.setOriginPoint(x, y);
                    cardSprite.setMoveAnimation(x, y, 30);
                }
                break;
            }
            // 扇形排列
            case 1: {
                // 扇形排列计算略复杂，不知道是否有跟简单的算法
                // =======================================
                // 总张角,弧度,垂直向上方向为0
                const totalAngle = 0.3;
                // 牌聚拢宽度
                const cardTotalWidth = ((cardAmount - 1) * 0.5 + 1) * cardWidth;
                // 这里要分两种宽度，牌聚拢的宽度是否大于容器宽度
                let offset = 0, spacing = 0;

                if (width >= cardTotalWidth) {
                    // 容器更宽或等于的情况
                    offset = (width - cardTotalWidth) / 2;
                    spacing = cardWidth / 2;
                } else {
                    // 容器宽比卡聚拢牌小的情况，需要将牌进一步紧凑压缩一下
                    // 如果1张牌仍然比容器宽的话那么容器宽度不合理
                    if (cardAmount === 1) {
                        throw new Error('容器宽度太小，无法容纳1张牌');
                    }
                    offset = 0;
                    spacing = (width - cardWidth) / (cardAmount - 1);
                }
                for (let i = 0; i < cardAmount; i++) {
                    const index = this._usedCard[i];
                    const cardSprite = this._cardSprite[index];
                    // 精灵锚点在底部中间，计算要考虑进去
                    const x = spacing * i + cardWidth / 2 + offset;
                    const y = height;
                    const angle = cardAmount === 1 ? 0 : -totalAngle / 2 + totalAngle / (cardAmount - 1) * i;
                    cardSprite.move(x, y);
                    cardSprite.rotation = angle;
                    cardSprite.setOriginPoint(x, y, angle);
                }
                break;
            }
        }
        this.sortChildren();
    }

    /**
     * 手牌精灵
     * @returns {Sprite_HandCard[]}
     */
    handCardSprite() {
        return this._usedCard.map(index => this._cardSprite[index]);
    }

    /**
     * 手牌对象
     * @returns {Game_Card[]}
     */
    handCardObject() {
        return this._usedCard.map(index => this._cardSprite[index].object());
    }

    /**
     * 是否动画中
     * @returns {boolean}
     */
    isAnimation() {
        let result = false;
        for (const spriteIndex of this._usedCard) {
            const sprite = this._cardSprite[spriteIndex];
            if (sprite.isAnimation()) {
                result = true;
                return result;
            }
        }
        return result;
    }

    updateContainer() {
        if (CardGameManager.isAnyWindowOpen()) return;
        this.processTouch();
        if (this._selectMode) {
            this.updateCardSelect();
        } else {
            this.updateCardSpriteDrag();
            this.updateDragTargetDetection();
        }
    }

    processTouch() {
        if (this._draging) return;
        let current = null;
        for (const cardIndex of this._usedCard) {
            const cardSprite = this._cardSprite[cardIndex];
            // 未启用的卡牌精灵不应该参与
            if (!cardSprite.visible) continue;
            if (cardSprite.hitTest()) {
                current = cardSprite;
            }
        }
        if (current !== this.current) {
            this.setCurrent(current);
        }
    }

    /**
     * 更新卡牌选择
     */
    updateCardSelect() {
        // 手牌选择模式
        if (TouchInput.isClicked() && this.current !== null) {
            this._selectCallback(this.current)
            this.current = null;
            this.clearSelect();
        }
    }

    /**
     * 更新卡牌精灵拖拽效果
     */
    updateCardSpriteDrag() {
        if (TouchInput.isTriggered()) {
            if (this.current !== null) this._draging = true;
            this._lastTouchPos = new Point(TouchInput.x, TouchInput.y);
        }
        if (this._draging && TouchInput.isPressed() && !!this.current) {
            const cx = TouchInput.x - this._lastTouchPos.x;
            const cy = TouchInput.y - this._lastTouchPos.y;
            this._lastTouchPos = new Point(TouchInput.x, TouchInput.y);
            this.current.move(this.current.x + cx, this.current.y + cy);
        }
        if (this._draging && !TouchInput.isPressed() && !!this.current) {
            this._draging = false;
            CardGameManager.requestPlayCard(this.current, this._target);
            this.setCurrent(null);
        }
    }

    /**
     * 更新拖拽索敌
     */
    updateDragTargetDetection() {
        if (!this._draging) return;
        const target = this.findTarget();
        this._target = target;
        if (target < 0) {
            if (!!this.current) {
                this.current.opacity = 255;
            }
        } else {
            this._target = target;
            if (!!this.current) {
                this.current.opacity = 180;
            }
        }
    }

    /**
     * 寻找光标或触摸点目标
     */
    findTarget() {
        const targets = this.parent.parent.enemySprite();
        for (let index = 0; index < targets.length; index++) {
            if (targets[index].isBeingTouched() && targets[index].battler().isAlive()) {
                return index;
            }
        }
        return -1;
    }


    /**
     * 回收卡牌精灵
     * @param {Sprite_HandCard} cardSprite 卡牌精灵
     */
    recycleCardSprite(cardSprite) {
        const index = this._cardSprite.indexOf(cardSprite);
        if (index === -1) {
            console.error("找不到卡牌精灵");
            return;
        }
        if (this._usedCard.includes(index)) {
            this._usedCard.remove(index);
            this._idleCard.push(index);
            // 不重置属性，方便表现各种卡牌特效
            cardSprite.abandon();
            this.sort();
        } else {
            console.error("使用卡牌索引不应该存在，请检查bug");
            return;
        }
    }

    /**
     * 放弃所有手牌
     */
    abandonAllHandCard() {
        const objects = [];
        const point = this.toLocal(CardGameManager.cemeteryPosition);
        for (const index of this._usedCard) {
            const sprite = this._cardSprite[index];
            sprite.setMoveAnimation(point.x, point.y, 30);
            sprite.setBlurAnimation(120, 30);
            sprite.setScaleAnimation(0.5, 0.5, 30);
            sprite.hide(50);
            objects.push(sprite.object());
        }
        this._idleCard.push(...this._usedCard);
        this._usedCard = [];
        return objects;
    }

    /**
     * 执行消失
     */
    applyDisappear(cardSprite) {
        const point = this.toLocal(new Point(Graphics.width / 2, Graphics.height / 2));
        const index = this._cardSprite.indexOf(cardSprite);
        this._usedCard.remove(index);
        this._idleCard.push(index);
        cardSprite.setMoveAnimation(point.x, point.y, 30);
        cardSprite.setBlurAnimation(0, 60);
        cardSprite.hide(60);
        this._effectPanel.setVanish(60);
        this.sort();
    }

    /**
     * 执行返回牌库
     */
    applyGoBack(cardSprite) {
        const point = this.toLocal(CardGameManager.deckPosition);
        const index = this._cardSprite.indexOf(cardSprite);
        this._usedCard.remove(index);
        this._idleCard.push(index);
        cardSprite.setMoveAnimation(point.x, point.y, 30);
        cardSprite.setScaleAnimation(0.5, 0.5, 30);
        cardSprite.setBlurAnimation(122, 30);
        cardSprite.hide(60);
        this._effectPanel.setVanish(60);
        this.sort();
    }

    /**
     * 开始手牌选择
     */
    setupSelect(tip, callback) {
        this._selectMode = true;
        this._effectPanel.show();
        this._effectPanel.setTitle(tip);
        this._selectCallback = callback.bind(this);
    }

    /**
     * 清除手牌选择
     */
    clearSelect() {
        this._selectMode = false;
        this._selectCallback = null;
    }

    /**
     * 设置特效面板
     * @param panel
     */
    setEffectPanel(panel) {
        this._effectPanel = panel;
    }
}